package com.atguigu.day3;

import java.util.concurrent.*;

public class MyThreadPoolDemo {
    //传统创建线程池方法，不建议使用，会导致资源耗尽
    /*public static void main(String[] args) {
        //ExecutorService executorService = Executors.newFixedThreadPool(10);//一池5工作池
        //ExecutorService executorService = Executors.newSingleThreadExecutor();//一池一线城
        ExecutorService executorService = Executors.newCachedThreadPool();//一池线程
        try {
            //模拟20个顾客进入银行来办理业务（请求线程）
            for (int i = 0; i < 20; i++) {
                int j = i;
                executorService.execute(() -> {
                    System.out.println(Thread.currentThread().getName() + "\t" + "给顾客：" + j + "\t办理业务");
                    //暂停线程
                    try {
                        TimeUnit.SECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                });
            }
        } finally {
            executorService.shutdown();
        }
    }*/

    public static void main(String[] args) {
        //System.out.println(Runtime.getRuntime().availableProcessors());//当前系统可用的处理器核心数

        ExecutorService threadPool = new ThreadPoolExecutor(
                2,
                //如何设置线程池大小，分为两种情况
                //1.是CPU密集型任务  例：大量计算  CPU核数+1
                //Runtime.getRuntime().availableProcessors() +1,
                //2.是I/O密集型任务  例：SQL查询，传输任务比较多  CPU核数*2
                Runtime.getRuntime().availableProcessors() * 2,
                1L,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(5),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.CallerRunsPolicy()
                //CallerRunsPolicy()“调用者运行"一种调节机制，该策略既不会抛弃任务，也不会抛出异常，而是将某些任务回退到调用者，从而降低新任务的流量
                //AbortPolicy()直接掀桌子，抛异常,DiscardPolicy()会直接抛弃任务，DiscardOldestPolicy()会抛弃队列中等待最近的线程
        );
        try {
            for (int i = 0; i < 20; i++) {
                int j = i;
                threadPool.execute(() -> {
                    System.out.println(Thread.currentThread().getName() + "\t" + "给顾客：" + j + "\t办理业务");
                    //暂停线程
                    try {
                        TimeUnit.SECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    //进入阻塞队列的最后运行，遍历阻塞队列需要时间，为了效率一般先运行非队列内的
                });
            }
        } finally {
            threadPool.shutdown();
        }
    }

}
